﻿/******************************************************************************
 * This file is part of libemb.
 *
 * libemb is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * libemb is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with libemb.  If not, see <http://www.gnu.org/licenses/>.
 *
 * Project: Embedme
 * Author : FergusZeng
 * Email  : cblock@126.com
 * git	  : https://git.oschina.net/cblock/embedme
 * Copyright 2014~2017 @ ShenZhen ,China
*******************************************************************************/
#ifndef __ATOMICVECTOR_H__
#define __ATOMICVECTOR_H__

#include "BaseType.h"
#include "Mutex.h"
#include <vector>
#include <queue>

namespace libemb{
/**
 *  \file   Atomic.h   
 *  \class  AtomicVar
 *  \brief  原子变量.
 */
template <class Type>
class AtomicVar{
public:
    AtomicVar();
    ~AtomicVar();
    Type getValue(void);
    void setValue(Type& value);
    bool testValue(Type& value);
private:
    MutexLock m_varMutex;
    Type m_value;
};

template <class Type>
AtomicVar<Type>::AtomicVar()
{}

template <class Type>
AtomicVar<Type>::~AtomicVar()
{}


template <class Type>
Type AtomicVar<Type>::getValue()
{
    AutoLock lock(&m_varMutex);
    return m_value;
}

template <class Type>
void AtomicVar<Type>::setValue(Type& value)
{
    AutoLock lock(&m_varMutex);
    m_value = value;
}

template <class Type>
bool AtomicVar<Type>::testValue(Type& value)
{
    AutoLock lock(&m_varMutex);
    return (m_value==value)?true:false;
}

/**
 *  \file   Atomic.h   
 *  \class  AtomicVector
 *  \brief  原子向量.
 */
template <class Type>
class AtomicVector{
public:
    AtomicVector();
    ~AtomicVector();
    void push_back(Type element);   /* 在最后插入一个元素 */
    void pop_back(void);            /* 删除最后一个元素 */
    Type front(void);
    Type back(void);
    void clear(void);               /* 清空所有元素 */
    bool empty(void);               /* 如果vector为空则返回真 */
    uint32 size(void);              /* 返回vector中元素的个数 */
    Type& operator[ ](int idx);     /* 数组操作符 */

private:
    MutexLock m_vectorMutex;
    std::vector<Type> m_vector;
};

template <class Type>
AtomicVector<Type>::AtomicVector()
{}

template <class Type>
AtomicVector<Type>::~AtomicVector()
{}

template <class Type>
void AtomicVector<Type>::push_back(Type element)
{
    m_vectorMutex.lock();
    m_vector.push_back(element);
    m_vectorMutex.unLock();
}

template <class Type>
void AtomicVector<Type>::pop_back()
{
    m_vectorMutex.lock();
    m_vector.pop_back();
    m_vectorMutex.unLock();
}

template <class Type>
Type AtomicVector<Type>::front()
{
    m_vectorMutex.lock();
    Type ret=m_vector.front();
    m_vectorMutex.unLock();
    return ret;
}

template <class Type>
Type AtomicVector<Type>::back()
{
    m_vectorMutex.lock();
    Type ret=m_vector.back();
    m_vectorMutex.unLock();
    return ret;
}

template <class Type>
void AtomicVector<Type>::clear(void)
{
    m_vectorMutex.lock();
    m_vector.clear();
    m_vectorMutex.unLock();
}

template <class Type>
bool AtomicVector<Type>::empty(void)
{
    m_vectorMutex.lock();
    bool ret = m_vector.empty();
    m_vectorMutex.unLock();
    return ret;
}

template <class Type>
unsigned int AtomicVector<Type>::size(void)
{
    m_vectorMutex.lock();
    uint32 ret = m_vector.size();
    m_vectorMutex.unLock();
    return ret;
}

template <class Type>
Type& AtomicVector<Type>::operator[ ](int idx)
{
    m_vectorMutex.lock();
    Type& ret = m_vector[idx];
    m_vectorMutex.unLock();
    return ret;
}

/**
 *  \file   Atomic.h   
 *  \class  AtomicQueue
 *  \brief  原子队列.
 */
template <class Type>
class AtomicQueue{
public:
    AtomicQueue();
    ~AtomicQueue();
    void push(Type element);    /* 在末尾加入一个元素 */
    void pop(void);             /* 删除第一个元素 */
    Type front(void);           /* 返回第一个元素 */
    Type back(void);            /* 返回最后一个元素 */
    bool empty(void);           /* 如果队列空则返回真 */
    uint32 size(void);          /* 返回队列中元素的个数 */
private:
    MutexLock m_queueMutex;
    std::queue<Type> m_queue;
};

template <class Type>
AtomicQueue<Type>::AtomicQueue()
{}

template <class Type>
AtomicQueue<Type>::~AtomicQueue()
{}

template <class Type>
void AtomicQueue<Type>::push(Type element)
{
    m_queueMutex.lock();
    m_queue.push(element);
    m_queueMutex.unLock();
}

template <class Type>
void AtomicQueue<Type>::pop(void)
{
    m_queueMutex.lock();
    m_queue.pop();
    m_queueMutex.unLock();
}

template <class Type>
Type AtomicQueue<Type>::front(void)
{
    m_queueMutex.lock();
    Type ret = m_queue.front();
    m_queueMutex.unLock();
    return ret;
}

template <class Type>
Type AtomicQueue<Type>::back(void)
{
    m_queueMutex.lock();
    Type ret = m_queue.back();
    m_queueMutex.unLock();
    return ret;
}

template <class Type>
bool AtomicQueue<Type>::empty(void)
{
    m_queueMutex.lock();
    bool ret = m_queue.empty();
    m_queueMutex.unLock();
    return ret;
}

template <class Type>
unsigned int AtomicQueue<Type>::size(void)
{
    m_queueMutex.lock();
    unsigned int ret = m_queue.size();
    m_queueMutex.unLock();
    return ret;
}
}

#endif
